// 项目目录结构示例：
// FileDBSystem/                ← 工作空间根目录
// ├── .vscode/                 ← VSCode 调试配置
// │   └── launch.json          ← Java 应用调试配置
// ├── FileDBSystem.java        ← 主程序源码文件
// └── README.md                ← 项目说明文件

// .vscode/launch.json 示例：
// {
//     "version": "0.2.0",
//     "configurations": [
//         {
//             "type": "java",
//             "name": "Debug FileDBSystem",
//             "request": "launch",
//             "mainClass": "FileDBSystem"
//         }
//     ]
// }

// FileDBSystem.java
import java.io.*;
import java.nio.file.*;
import java.util.*;

public class FileDBSystem {
    private static final Path ROOT = Paths.get(System.getProperty("user.dir"));
    private static Path currentDb = null;
    private static final Scanner SCANNER = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("欢迎使用文件数据库系统 (输入 exit; 退出)");
        while (true) {
            System.out.print("> ");
            String line = SCANNER.nextLine().trim();
            if (!line.endsWith(";")) {
                System.out.println("命令必须以分号结尾");
                continue;
            }
            String cmd = line.substring(0, line.length() - 1).trim();
            if (cmd.equalsIgnoreCase("exit")) break;
            try {
                execute(cmd);
            } catch (Exception e) {
                System.out.println("执行出错: " + e.getMessage());
            }
        }
        System.out.println("已退出系统。");
    }

    private static void execute(String cmd) throws IOException {
        String lc = cmd.toLowerCase();
        if (lc.startsWith("create database ")) {
            createDatabase(cmd.substring(16).trim());
        } else if (lc.startsWith("drop database ")) {
            dropDatabase(cmd.substring(14).trim());
        } else if (lc.startsWith("use ")) {
            useDatabase(cmd.substring(4).trim());
        } else if (lc.startsWith("create table ")) {
            createTable(cmd.substring(13).trim());
        } else if (lc.startsWith("drop table ")) {
            dropTable(cmd.substring(11).trim());
        } else if (lc.startsWith("info table ")) {
            infoTable(cmd.substring(11).trim());
        } else if (lc.startsWith("insert into ")) {
            insertRecord(cmd.substring(12).trim());
        } else if (lc.startsWith("delete from ")) {
            deleteRecord(cmd.substring(12).trim());
        } else if (lc.startsWith("select ")) {
            selectRecord(cmd.substring(6).trim());
        } else {
            System.out.println("未知命令: " + cmd);
        }
    }

    private static void createDatabase(String name) throws IOException {
        Path db = ROOT.resolve(name);
        if (Files.exists(db)) {
            System.out.println("数据库已存在: " + name);
        } else {
            Files.createDirectory(db);
            System.out.println("创建数据库成功: " + name);
        }
    }

    private static void dropDatabase(String name) throws IOException {
        Path db = ROOT.resolve(name);
        if (!Files.exists(db)) {
            System.out.println("数据库不存在: " + name);
        } else {
            deleteRecursively(db);
            System.out.println("删除数据库成功: " + name);
        }
    }

    private static void useDatabase(String name) {
        Path db = ROOT.resolve(name);
        if (!Files.exists(db) || !Files.isDirectory(db)) {
            System.out.println("数据库不存在: " + name);
        } else {
            currentDb = db;
            System.out.println("当前数据库: " + name);
        }
    }

    private static void createTable(String rest) throws IOException {
        checkDbSelected();
        int idx = rest.indexOf('(');
        String name = rest.substring(0, idx).trim();
        String cols = rest.substring(idx + 1, rest.lastIndexOf(')')).trim();
        Path tbl = currentDb.resolve(name + ".tbl");
        Path meta = currentDb.resolve(name + ".schema");
        if (Files.exists(tbl)) {
            System.out.println("数据表已存在: " + name);
            return;
        }
        Files.createFile(tbl);
        Files.write(meta, cols.getBytes());
        System.out.println("创建表成功: " + name);
    }

    private static void dropTable(String name) throws IOException {
        checkDbSelected();
        Files.deleteIfExists(currentDb.resolve(name + ".tbl"));
        Files.deleteIfExists(currentDb.resolve(name + ".schema"));
        System.out.println("删除表成功: " + name);
    }

    private static void infoTable(String name) throws IOException {
        checkDbSelected();
        Path meta = currentDb.resolve(name + ".schema");
        Path tbl = currentDb.resolve(name + ".tbl");
        if (!Files.exists(meta)) {
            System.out.println("数据表不存在: " + name);
            return;
        }
        String cols = new String(Files.readAllBytes(meta));
        long count = Files.lines(tbl).count();
        System.out.println("表 " + name + " 字段: " + cols);
        System.out.println("记录数: " + count);
    }

    private static void insertRecord(String rest) throws IOException {
        checkDbSelected();
        int idx = rest.toLowerCase().indexOf(" set ");
        String name = rest.substring(0, idx).trim();
        String body = rest.substring(idx + 5).trim();
        Path tbl = currentDb.resolve(name + ".tbl");
        if (!Files.exists(tbl)) {
            System.out.println("数据表不存在: " + name);
            return;
        }
        Map<String, String> map = new LinkedHashMap<>();
        for (String kv : body.split(",")) {
            String[] parts = kv.split("=");
            map.put(parts[0].trim(), parts[1].trim().replace("'", ""));
        }
        String line = String.join(",", map.values());
        Files.write(tbl, (line + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
        System.out.println("插入成功: " + line);
    }

    private static void deleteRecord(String rest) throws IOException {
        checkDbSelected();
        String[] parts = rest.split(" where ", 2);
        String name = parts[0].trim();
        Path tbl = currentDb.resolve(name + ".tbl");
        if (!Files.exists(tbl)) {
            System.out.println("数据表不存在: " + name);
            return;
        }
        List<String> lines = Files.readAllLines(tbl);
        if (parts.length == 1) {
            Files.write(tbl, new byte[0]);
            System.out.println("已删除所有记录");
            return;
        }
        String cond = parts[1].trim();
        String[] condParts = cond.split("(?<=[<>=])|(?=[<>=])");
        String col = condParts[0].trim();
        String op = condParts[1].trim();
        String val = condParts[2].trim().replace("'", "");
        List<String> out = new ArrayList<>();
        int colIdx = getColumnIndex(name, col);
        for (String l : lines) {
            String[] vs = l.split(",");
            String v = vs[colIdx];
            boolean keep;
            switch (op) {
                case "=": keep = v.equals(val); break;
                case "<": keep = Double.parseDouble(v) < Double.parseDouble(val); break;
                case ">": keep = Double.parseDouble(v) > Double.parseDouble(val); break;
                default: keep = true;
            }
            if (!keep) out.add(l);
        }
        Files.write(tbl, out);
        System.out.println("删除完成，保留记录: " + out.size());
    }

    private static void selectRecord(String rest) throws IOException {
        checkDbSelected();
        String[] parts = rest.split(" from ", 2);
        String fields = parts[0].trim();
        String tail = parts[1].trim();
        String[] p2 = tail.split(" order by ", 2);
        String left = p2[0];
        String orderClause = p2.length > 1 ? p2[1].trim() : null;
        String[] p3 = left.split(" where ", 2);
        String name = p3[0].trim();
        String cond = p3.length > 1 ? p3[1].trim() : null;

        Path tbl = currentDb.resolve(name + ".tbl");
        if (!Files.exists(tbl)) {
            System.out.println("数据表不存在: " + name);
            return;
        }
        List<String> lines = Files.readAllLines(tbl);
        if (cond != null) {
            String[] condParts = cond.split("(?<=[<>=])|(?=[<>=])");
            String col = condParts[0].trim();
            String op = condParts[1].trim();
            String val = condParts[2].trim().replace("'", "" );
            int colIdx = getColumnIndex(name, col);
            lines.removeIf(line -> {
                String v = line.split(",")[colIdx];
                switch (op) {
                    case "=": return !v.equals(val);
                    case "<": return !(Double.parseDouble(v) < Double.parseDouble(val));
                    case ">": return !(Double.parseDouble(v) > Double.parseDouble(val));
                }
                return false;
            });
        }
        if (orderClause != null) {
            String[] oc = orderClause.split(" ");
            String col = oc[0].trim();
            boolean desc = oc.length > 1 && oc[1].equalsIgnoreCase("desc");
            int colIdx = getColumnIndex(name, col);
            lines.sort((a, b) -> {
                String va = a.split(",")[colIdx];
                String vb = b.split(",")[colIdx];
                int cmp;
                try { cmp = Double.compare(Double.parseDouble(va), Double.parseDouble(vb)); }
                catch (Exception e) { cmp = va.compareTo(vb); }
                return desc ? -cmp : cmp;
            });
        }
        for (String l : lines) System.out.println(l);
    }

    private static int getColumnIndex(String tableName, String colName) throws IOException {
        Path meta = currentDb.resolve(tableName + ".schema");
        String[] fields = new String(Files.readAllBytes(meta)).split(",");
        for (int i = 0; i < fields.length; i++) {
            String[] kv = fields[i].trim().split(" ");
            if (kv[1].equalsIgnoreCase(colName)) return i;
        }
        throw new IllegalArgumentException("字段不存在: " + colName);
    }

    private static void checkDbSelected() {
        if (currentDb == null) throw new IllegalStateException("尚未选择数据库");
    }

    private static void deleteRecursively(Path path) throws IOException {
        if (Files.isDirectory(path)) {
            try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
                for (Path p : ds) deleteRecursively(p);
            }
        }
        Files.delete(path);
    }
}
